using System;
using System.Xml;
using System.Windows.Forms;
using System.Text;
using System.IO;

namespace WinSSHMenu
{
    /// <summary>
    /// Summary description for TreeViewSerializer.
    /// </summary>
    public class MenuSerializer
    {

        // Xml tag for node, e.g. 'node' in case of <node></node>
        private const string XmlNodeTag = "node";

        // Xml attributes for node e.g. <node text="Asia" tag="" imageindex="1"></node>
        private const string XmlNodeTextAtt = "text";
        private const string XmlNodeTagAtt = "tag";
        private const string XmlNodeImageIndexAtt = "imageindex";
        private string defaultNode = 
            "<?xml version=\"1.0\" encoding=\"us-ascii\"?><TreeView><node text=\"Server List\" imageindex=\"6\" tag=\"ROOTNODE\"></node></TreeView>";

        public MenuSerializer()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        public void DeserializeMenu(ContextMenuStrip rootMenu, string fileName)
        {
            XmlTextReader reader = null;
            try
            {
                
                if (!File.Exists(fileName))
                {
                    // Menu file not found, create one
                    FileStream fs = File.Create(fileName);
                    fs.Close();
                    StreamWriter sw = new StreamWriter(fileName);
                    sw.WriteLine(defaultNode);
                    sw.Close();
                }
                
                reader =
                    new XmlTextReader(fileName);

                ToolStripMenuItem parentItem = null;

                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        if (reader.Name == XmlNodeTag)
                        {
                            ToolStripMenuItem item = new ToolStripMenuItem();
                            bool isEmptyElement = reader.IsEmptyElement;

                            // loading node attributes
                            int attributeCount = reader.AttributeCount;
                            if (attributeCount > 0)
                            {
                                for (int i = 0; i < attributeCount; i++)
                                {
                                    reader.MoveToAttribute(i);

                                    SetAttributeValue(item, reader.Name, reader.Value);
                                }
                            }

                            // add new node to Parent Node or TreeView
                            if (parentItem != null)
                            {
                                if (item.Tag.ToString() != Constants.TYPE_SUBMENU &&
                                    item.Tag.ToString() != Constants.TYPE_ROOTNODE)
                                {
                                    item.Click += 
                                        new System.EventHandler(WinSSHMenu.itemToolStripMenuItem_Click);
                                }
                                // BUG: There is a bug that will make the 
                                // app crash if a seperator is added to the
                                // root node. For now, we'll skip any that
                                // exist at the root level
                                if (item.Tag.ToString().Equals(Constants.TYPE_SEPARATOR))
                                {
                                    if (!parentItem.Tag.ToString().Equals(Constants.TYPE_ROOTNODE))
                                    {
                                        parentItem.DropDownItems.Add(new ToolStripSeparator());
                                    }
                                    else
                                    {
                                        item.Visible = false;
                                        parentItem.DropDownItems.Add(item);
                                    }
                                }
                                else
                                {
                                    parentItem.DropDownItems.Add(item);       
                                }
                                
                            }
                            else
                            {
                                item.Text = "SSH";
                                rootMenu.Items.Add(item);
                            }
                            // Making current node a parent if it's not empty
                            // Otherwise if it's empty and a submenu, make
                            // it disabled. 
                            if (!isEmptyElement)
                            {

                                
                                parentItem = item;
                                if (!parentItem.Tag.ToString().Equals(Constants.TYPE_ROOTNODE))
                                {
                                    ToolStripMenuItem openAll = 
                                        new ToolStripMenuItem();
                                    openAll.Text = "Open All Windows";
                                    openAll.Click += 
                                        new System.EventHandler(WinSSHMenu.openAllWindows_Click);
                                    item.DropDown.Items.Add(openAll);
                                    item.DropDown.Items.Add(new ToolStripSeparator());

                                }
                            }
                            else if (isEmptyElement && item.Tag.ToString() == 
                                                       Constants.TYPE_SUBMENU)
                            {
                                item.Enabled = false;
                            }

                        }
                    }
                    // moving up to in TreeView if end tag is encountered
                    else if (reader.NodeType == XmlNodeType.EndElement)
                    {
                        if (reader.Name == XmlNodeTag)
                        {
                            parentItem = (ToolStripMenuItem)parentItem.OwnerItem;
                        }
                    }
                    else if (reader.NodeType == XmlNodeType.XmlDeclaration)
                    { //Ignore Xml Declaration                    
                    }
                    else if (reader.NodeType == XmlNodeType.None)
                    {
                        return;
                    }
                    else if (reader.NodeType == XmlNodeType.Text)
                    {
                        parentItem.DropDownItems.Add(reader.Value);
                    }
                }
            }
            finally
            {
                // enabling redrawing of treeview after all nodes are added
                reader.Close();
            }
        }

        /// <summary>
        /// Used by Deserialize method for setting properties of TreeNode from xml node attributes
        /// </summary>
        /// <param name="node"></param>
        /// <param name="propertyName"></param>
        /// <param name="value"></param>
        private void SetAttributeValue(ToolStripMenuItem item, string propertyName, string value)
        {
            if (propertyName == XmlNodeTextAtt)
            {
                item.Text = value;
            }
            else if (propertyName == XmlNodeImageIndexAtt)
            {
                item.ImageIndex = int.Parse(value);
            }
            else if (propertyName == XmlNodeTagAtt)
            {
                item.Tag = value;
            }
        }

    }
}